/**
 * 
 */
package com.jbat.gwt.tiledmapcreator.client.activities;

import com.jbat.gwt.tiledmapcreator.client.common.CanvasLocation;
import com.jbat.gwt.tiledmapcreator.client.common.MapLocation;
import com.jbat.gwt.tiledmapcreator.client.common.PositionConverter;
import com.jbat.gwt.tiledmapcreator.client.common.color.Color;
import com.jbat.gwt.tiledmapcreator.client.common.color.Colors;
import com.jbat.gwt.tiledmapcreator.client.common.color.DefinedColors;
import com.jbat.gwt.tiledmapcreator.client.places.MapDesignPlace;
import com.jbat.gwt.tiledmapcreator.client.views.EditMapView;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.touch.client.Point;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

/**
 * 
 */
public class EditMapActivity extends AbstractActivity implements EditMapView.Presenter {
  private EditMapView view;
  private int rows;
  private int cols;
  private MapLocation currentSelectedCell;
  private String[][] urlMap; // the model class to convert between canvas coords and row/col
  private PositionConverter converter;

  @Inject
  public EditMapActivity(EditMapView view, @Assisted MapDesignPlace place) {
    this.view = view;
    this.rows = place.getRows();
    this.cols = place.getCols();
    urlMap = new String[rows][cols];
    converter = new PositionConverter(rows, cols);
  }

  @Override
  public void drawCell(String string, Point canvasPoint) {
    MapLocation mapLoc =
        converter.getMapLocationAtCoords((int) canvasPoint.getX(), (int) canvasPoint.getY());
    drawCell(string, mapLoc.getRow(), mapLoc.getCol());
  }  

  /**
   * @return the cols
   */
  int getCols() {
    return cols;
  }

  /**
   * @return the rows
   */
  int getRows() {
    return rows;
  }

  @Override
  public void select(Point canvasPoint) {
    // deselect previous cell if there was one
    if (currentSelectedCell != null) {
      deselectCell(currentSelectedCell.getRow(), currentSelectedCell.getCol());
    }

    MapLocation mapLoc =
        converter.getMapLocationAtCoords((int) canvasPoint.getX(), (int) canvasPoint.getY());

    // set the current selected cell to equal the above location
    currentSelectedCell = mapLoc;

    selectCell(mapLoc.getRow(), mapLoc.getCol());
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.google.gwt.activity.shared.Activity#start(com.google.gwt.user.client
   * .ui.AcceptsOneWidget, com.google.gwt.event.shared.EventBus)
   */
  @Override
  public void start(AcceptsOneWidget panel, EventBus eventBus) {
    view.setPresenter(this);
    panel.setWidget(view);

    // get the units per cell of the converter
    int unitsPerCell = converter.getUnitsPerCell();
    int xUnits = cols * unitsPerCell;
    int yUnits = rows * unitsPerCell;
    xUnits = xUnits + 2; // + 2 to get full line width on edges
    yUnits = yUnits + 2;
    // set the canvas coordinate space
    view.setMapSize(xUnits, yUnits);

    // draw the grid
    drawGrid(xUnits, yUnits, unitsPerCell);

    // draw the map
    drawMap();
  }

  private void deselectCell(int row, int col) {
    // get upper left x and y positions
    CanvasLocation canLoc = converter.getCanvasArea(row, col);
    Point upperLeft = canLoc.getUpperLeftPos();

    // get width and height
    int width = converter.getUnitsPerCell();
    int height = width;

    // set the color to unselected
    Color unselectedColor = Colors.getInstance(DefinedColors.UNSELECTED);
    view.drawRect(unselectedColor, upperLeft, width, height);
  }

  private void drawCell(String string, int row, int col) {
    // convert the string into a safe uri
    SafeUri safeStr = UriUtils.fromTrustedString(string);

    // get upper left x and y positions
    CanvasLocation canLoc = converter.getCanvasArea(row, col);
    Point upperLeft = canLoc.getUpperLeftPos();

    // get width and height
    int width = converter.getUnitsPerCell();
    int height = width;

    // draw the object
    view.drawImageAt(safeStr, upperLeft, width, height);
  }

  private void drawGrid(int xUnits, int yUnits, int unitsPerCell) {
    // draw the x lines
    for (int i = 1; i < xUnits; i = i + unitsPerCell) {
      Point start = new Point(i, 0);
      Point end = new Point(i, yUnits - 1); // - 1 to get full width on edge

      // set the color to unselected
      Color unselectedColor = Colors.getInstance(DefinedColors.UNSELECTED);
      view.drawLine(unselectedColor, start, end);
    }

    // draw the y lines
    for (int i = 1; i < yUnits; i = i + unitsPerCell) {
      Point start = new Point(0, i);
      Point end = new Point(xUnits - 1, i); // - 1 to get full width on edge

      // set the color to unselected
      Color unselectedColor = Colors.getInstance(DefinedColors.UNSELECTED);
      view.drawLine(unselectedColor, start, end);
    }
  }

  private void drawMap() {
    // for each cell in the map, draw the cell
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++) {
        String urlString = urlMap[r][c];

        // check for null, empty string
        if (urlString != null && !urlString.isEmpty()) {
          drawCell(urlString, r, c);
        }
      }
    }
  }

  private void selectCell(int row, int col) {
    // get upper left x and y positions
    CanvasLocation canLoc = converter.getCanvasArea(row, col);
    Point upperLeft = canLoc.getUpperLeftPos();

    // get width and height
    int width = converter.getUnitsPerCell();
    int height = width;

    // set the color to selected
    Color selectedColor = Colors.getInstance(DefinedColors.SELECTED);
    view.drawRect(selectedColor, upperLeft, width, height);
  }

}
